namespace System.Xml.Serialization
{
    using System;
    using System.IO;

    [Serializable]
    public abstract class XmlStringSerializer<T> : XmlStreamSerializer<T>, IXmlTypeSerializer<T, string>
    {
        protected XmlStringSerializer() { }

        protected abstract byte[] Deserialize(string data);
        protected abstract string Serialize(byte[] data);

        protected virtual T InternalStringDeserialize(string data, IXmlTypeFormatter formatter)
        {
            lock (((XmlStringSerializer<T>)this))
            {
                if (!string.IsNullOrEmpty(data))
                {
                    try
                    {
                        using (MemoryStream stream = new MemoryStream(this.Deserialize(data)))
                        {
                            return InternalStreamDeserialize(stream, formatter);
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new XmlSerializationException();
                        //PluginLog.WriteErrorSync(ex);
                    }
                }
                return default(T);
            }
        }

        protected virtual string InternalStringSerialize(T obj, IXmlTypeFormatter formatter)
        {
            lock (((XmlStringSerializer<T>)this))
            {
                if (!object.Equals(obj, default(T)))
                {
                    try
                    {
                        using (MemoryStream stream = base.InternalStreamSerialize(obj, formatter))
                        {
                            return this.Serialize(stream.ToArray());
                        }

                    }
                    catch (Exception ex)
                    {
                        throw new XmlSerializationException();
                        //PluginLog.WriteErrorSync(ex);
                    }
                }
                return null;
            }
        }

        T IXmlTypeSerializer<T, string>.Deserialize(string data)
        {
            return this.InternalStringDeserialize(data, XmlTypeFormatter);
        }

        T IXmlTypeSerializer<T, string>.Deserialize(string data, IXmlRuntimeFormatter formatter)
        {
            try
            {
                if (formatter != null)
                {
                    return this.InternalStringDeserialize(data, formatter);
                }
            }
            catch (Exception ex)
            {
                //PluginLog.WriteErrorSync(ex);
            }
            return this.InternalStringDeserialize(data, XmlTypeFormatter);
        }

        string IXmlTypeSerializer<T, string>.Serialize(T obj)
        {
            return this.InternalStringSerialize(obj, XmlTypeFormatter);
        }

        string IXmlTypeSerializer<T, string>.Serialize(T obj, IXmlRuntimeFormatter formatter)
        {
            try
            {
                if (formatter != null)
                {
                    return this.InternalStringSerialize(obj, formatter);
                }
            }
            catch (Exception ex)
            {
                //PluginLog.WriteErrorSync(ex);
            }
            return this.InternalStringSerialize(obj, XmlTypeFormatter);
        }
    }
}

